#ifndef _SESSION_MGR_CONFIGGENERATOR_H
#define _SESSION_MGR_CONFIGGENERATOR_H

#include <cstddef>

#include <string>
#include <utility>

#include <tr1/memory>

#include "types.h"

namespace session_mgr
{
    class ConfigGenerator
    {
    public:
        ConfigGenerator();
        virtual ~ConfigGenerator() {}
        
        /**
         * Plugin-independent options:
         *   -- window= %u x %u
         *   -- buffer= %u x %u
         *   -- view  = %lf x %lf x %lf
         *   -- host  = %u.%u.%u.%u
         *   -- port  = %u
         */
        bool hasOption(std::string const& key);
        bool setOption(std::string const& key, std::string const& value);
        
        virtual bool ready(std::string *errorMessage);
        
        /**
         * Make sure the generator is ready() before calling this, or the
         * result is undefined.
         */
        virtual std::string generateConfig
        (ClientConnection const clients[], std::size_t clients_count) = 0;
        
        std::string getFormat(std::string const& key);
        
    protected:
        /**
         * Plugin-independent options will never be passed to these functions,
         * thus needn't to be reimplemented.
         */
        virtual bool doHasOption(std::string const& key);
        virtual bool doSetOption(std::string const& key, std::string const& value);
        
        /**
         * This message is only used for error response. However, it's
         * recommended that it matches the plugin's parsing procedure.
         */
        virtual std::string doGetFormat(std::string const& key);
        
        /**
         * Check for all unset or invalid set options, useful when the plugin
         * needs all the default options.
         * 
         * Return true iff all options is correctly set.
         * 
         * If missingOption is not NULL, the first missing option is written
         * into it.
         */
        bool defaultCheck(std::string *missingOption);
        
        ClientConnection appNode;
        unsigned windowWidth, windowHeight;
        unsigned bufferWidth, bufferHeight;
        double viewWidth, viewHeight, viewDepth;
        
    private:
        ConfigGenerator(ConfigGenerator const&);
        ConfigGenerator& operator = (ConfigGenerator const&);
    };
    
    typedef std::tr1::shared_ptr<ConfigGenerator> ConfigGeneratorPtr;
}

#endif
